/**
 * Created with CLion.
 * Description: 
 * User: loong
 * Date: 2025/5/20
 * Time: 23:05
 */

#include "Enemy.h"

#include "Player.h"
#include "affiliate/Collider.h"
#include "affiliate/SpriteAnim.h"
#include "raw/Stats.h"

#include <glm/geometric.hpp>
Enemy * Enemy::AddEnemyChild(Object * _parent, glm::vec2 _pos, Player * _target)
{
    auto enemy = new Enemy();
    enemy->Init();
    enemy->SetPosition(_pos);
    enemy->SetTarget(_target);
    if(nullptr != _parent)
        _parent->AddChild(enemy);
    return enemy;
}

void Enemy::Init()
{
    Actor::Init();
    anim_normal_ = SpriteAnim::AddSpriteAnimChild(this, "../assets/sprite/ghost-Sheet.png", 2.0f);
    anim_hurt_   = SpriteAnim::AddSpriteAnimChild(this, "../assets/sprite/ghostHurt-Sheet.png", 2.0f);
    anim_die_    = SpriteAnim::AddSpriteAnimChild(this, "../assets/sprite/ghostDead-Sheet.png", 2.0f);
    anim_hurt_->SetActive(false);
    anim_die_->SetActive(false);
    anim_die_->SetLoop(false);

    current_anim_ = anim_normal_;

    collider_ = Collider::AddColliderChild(this, anim_hurt_->GetSize());
    stats_    = Stats::AddStatsChild(this);

    SetType(ObjectType::ENEMY);
}

void Enemy::Update(float _dt)
{
    Actor::Update(_dt);

    if(target_->IsActive()) {
        AimTarget(target_);
        Move(_dt);

        Attack();
    }

    CheckState();
    Remove();
}

void Enemy::AimTarget(Player * _target)
{
    if(_target == nullptr)
        return;
    auto direction = _target->GetPosition() - this->GetPosition();

    direction = glm::normalize(direction);
    velocity_ = direction * max_speed_;
}

void Enemy::CheckState()
{
    State new_state;
    if (stats_->GetHealth() <= 0)
        new_state = State::DIE;
    else if (stats_->IsInvincible())
        new_state = State::HURT;
    else
        new_state = State::NORMAL;

    if (new_state != current_state_)
        ChangeState(new_state);
}

void Enemy::ChangeState(State _state)
{
    current_state_ = _state;

    current_anim_->SetActive(false);
    switch(current_state_) {
        case State::NORMAL:
            current_anim_ = anim_normal_;
            current_anim_->SetActive(true);
            break;
        case State::HURT:
            current_anim_ = anim_hurt_;
            current_anim_->SetActive(true);
            break;
        case State::DIE:
            current_anim_ = anim_die_;
            current_anim_->SetActive(true);
            break;
    }
}

void Enemy::Remove()
{
    if(anim_die_->IsFinish()) {
        need_remove_ = true;
    }
}

void Enemy::Attack()
{
    if(nullptr == collider_ || nullptr == target_ || target_->GetCollider() == nullptr)
        return;
    if(collider_->IsColliding(target_->GetCollider())) {
        if(nullptr != stats_ && nullptr != target_->GetStats()) {
            target_->TakeDamage(stats_->GetDamage());
        }
    }
}